package org.ragdollcat.first.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.ragdollcat.first.api.ai.aliyun.model.CreateOutPaintingTaskRequest;
import org.ragdollcat.first.api.ai.aliyun.model.CreateOutPaintingTaskResponse;
import org.ragdollcat.first.api.ai.aliyun.model.GetOutPaintingTaskResponse;
import org.ragdollcat.first.api.ai.aliyun.service.AliyunAIService;
import org.ragdollcat.first.common.DeleteRequest;
import org.ragdollcat.first.constants.UserConstant;
import org.ragdollcat.first.exception.BusinessException;
import org.ragdollcat.first.exception.ErrorCode;
import org.ragdollcat.first.exception.ThrowUtils;
import org.ragdollcat.first.manager.CosManager;
import org.ragdollcat.first.manager.upload.AbsFileUpload;
import org.ragdollcat.first.manager.upload.CommonFileUpload;
import org.ragdollcat.first.manager.upload.UrlFileUpload;
import org.ragdollcat.first.mapper.PictureFetchRecordMapper;
import org.ragdollcat.first.mapper.PictureMapper;
import org.ragdollcat.first.model.dto.picture.*;
import org.ragdollcat.first.model.entity.Picture;
import org.ragdollcat.first.model.entity.PictureFetchRecord;
import org.ragdollcat.first.model.entity.Space;
import org.ragdollcat.first.model.entity.User;
import org.ragdollcat.first.model.enums.PictureReviewStatusEnum;
import org.ragdollcat.first.model.vo.PictureVO;
import org.ragdollcat.first.service.PictureFetchRecordService;
import org.ragdollcat.first.service.PictureService;
import org.ragdollcat.first.service.SpaceService;
import org.ragdollcat.first.service.UserService;
import org.ragdollcat.first.util.ColorSimilarUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.io.IOException;
import java.util.List;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 86158
 * @description 针对表【picture(图片)】的数据库操作Service实现
 * @createDate 2025-08-17 17:47:37
 */
@Service
@Slf4j
public class PictureServiceImpl extends ServiceImpl<PictureMapper, Picture>
        implements PictureService {


    //    @Resource
//    private FileManager fileManager;
    @Resource
    private CommonFileUpload commonFileUpload;

    @Resource
    private UrlFileUpload urlFileUpload;

    @Resource
    private UserService userService;

    @Resource
    private CosManager cosManager;

    @Resource
    private SpaceService spaceService;

    @Resource
    private TransactionTemplate transactionTemplate;

    @Resource
    private AliyunAIService aliyunAIService;

    @Resource
    private PictureFetchRecordService pictureFetchRecordService;


    /**
     * 上传图片
     *
     * @param source               图片信息对象
     * @param pictureUploadRequest 上传图片请求对象
     * @param user                 当前登录人信息
     * @return 脱敏后的图片
     */
    @Override
    public PictureVO uploadPicture(Object source, PictureUploadRequest pictureUploadRequest, User user) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(user), ErrorCode.NOT_LOGIN_ERROR, "请先登录");
        ThrowUtils.throwIf(ObjUtil.isEmpty(pictureUploadRequest), ErrorCode.PARAMS_ERROR, "请求参数不能为空");
        Long id = pictureUploadRequest.getId();
        //校验空间
        Long spaceId = spaceService.vaildUploadSpace(pictureUploadRequest, user);

        //如果有id就是更新，没有id就是新增
        //调用上传图片的方法，文件前缀是picture/用户ID
        //根据当前是url上传图片还是文件上传图片进行区分
        AbsFileUpload absFileUpload = null;
        UploadPictureResult uploadPictureResult = null;
        if (source instanceof MultipartFile) {
            uploadPictureResult = commonFileUpload.uploadPicture(source, makeUploadPathPrefix(spaceId, user));
        } else {
            uploadPictureResult = urlFileUpload.uploadPicture(source, makeUploadPathPrefix(spaceId, user));
        }

        //构造要入库的信息
        Picture picture = new Picture();
        picture.setUrl(uploadPictureResult.getUrl());
        picture.setName(StrUtil.isNotBlank(pictureUploadRequest.getPicName()) ? pictureUploadRequest.getPicName() : uploadPictureResult.getPicName());
        picture.setPicSize(uploadPictureResult.getPicSize());
        picture.setPicWidth(uploadPictureResult.getPicWidth());
        picture.setPicHeight(uploadPictureResult.getPicHeight());
        picture.setPicScale(uploadPictureResult.getPicScale());
        picture.setPicFormat(uploadPictureResult.getPicFormat());
        picture.setUserId(user.getId());
        //设置缩略图地址，用于首页展示
        picture.setThumbnailUrl(uploadPictureResult.getThumbnailUrl());
        //设置图片色调，用于获取按照颜色搜图结果
        picture.setPicColor(uploadPictureResult.getPicColor());
        //填充审批参数
        this.fillCheckParams(picture, user, false);
        //需要判断ID是否存在表中
        if (id != null) {
            ThrowUtils.throwIf(!this.lambdaQuery().eq(Picture::getId, id).exists(), ErrorCode.OPERATION_ERROR, "需要编辑的图片信息不存在");
            picture.setId(id);
            picture.setEditTime(new Date());
        }
        //设置空间
        picture.setSpaceId(spaceId);
        //入库，并且计算额度
        transactionTemplate.execute(status -> {
            ThrowUtils.throwIf(!saveOrUpdate(picture), ErrorCode.OPERATION_ERROR, "图片上传失败！");
            if (spaceId != null) {
                ThrowUtils.throwIf(!spaceService.lambdaUpdate().eq(Space::getId, spaceId)
                        .setSql("totalSize = totalSize + " + picture.getPicSize())
                        .setSql("totalCount = totalCount + 1")
                        .update(), ErrorCode.OPERATION_ERROR, "扣减额度失败！");
            }
            return null;
        });

        //脱敏返回
        return PictureVO.objToVo(picture);
    }

    /**
     * 制作图片上传前缀，根据有无spaceId进行划分
     * 没有spaceId就放在picture下，拼接上用户Id
     * 否则在picture下再加一层目录，拼接上空间ID
     *
     * @param spaceId
     * @param user
     * @return
     */
    private String makeUploadPathPrefix(Long spaceId, User user) {
        String uploadPathPrefix = null;
        if (spaceId == null) {
            uploadPathPrefix = String.format("/%s/%s", "picture/public", user.getId());
        } else {
            uploadPathPrefix = String.format("/%s/%s", "picture/space", spaceId);
        }
        return uploadPathPrefix;
    }

    /**
     * 图片更新参数校验
     *
     * @param pictureUpdateRequest
     */
    @Override
    public void vaildUpdPicParam(PictureUpdateRequest pictureUpdateRequest) {
        Long id = pictureUpdateRequest.getId();
        ThrowUtils.throwIf(ObjUtil.isEmpty(id) || id < 0, ErrorCode.PARAMS_ERROR);
        String name = pictureUpdateRequest.getName();
        ThrowUtils.throwIf(StrUtil.isNotBlank(name) && name.length() > 100, ErrorCode.PARAMS_ERROR, "图片长度过长");
        String introduction = pictureUpdateRequest.getIntroduction();
        ThrowUtils.throwIf(StrUtil.isNotBlank(introduction) && introduction.length() > 800, ErrorCode.PARAMS_ERROR, "简介过长");
    }

    /**
     * 分页获取图片列表，无需脱敏
     * 无需限制条数
     * 条件查询
     *
     * @param pictureQueryRequest
     * @return
     */
    @Override
    public Page<Picture> getPicPage(PictureQueryRequest pictureQueryRequest) {
        return page(
                new Page<>(
                        pictureQueryRequest.getCurrent(),
                        pictureQueryRequest.getPageSize()),
                composePicQueryWrapper(pictureQueryRequest));
    }

    /**
     * 组装图片查询条件
     *
     * @param pictureQueryRequest
     * @return
     */
    @Override
    public Wrapper<Picture> composePicQueryWrapper(PictureQueryRequest pictureQueryRequest) {
        QueryWrapper<Picture> pictureQueryWrapper = new QueryWrapper<>();
        Long id = pictureQueryRequest.getId();
        String name = pictureQueryRequest.getName();
        String introduction = pictureQueryRequest.getIntroduction();
        String category = pictureQueryRequest.getCategory();
        List<String> tags = pictureQueryRequest.getTags();
        Long picSize = pictureQueryRequest.getPicSize();
        Integer picWidth = pictureQueryRequest.getPicWidth();
        Integer picHeight = pictureQueryRequest.getPicHeight();
        Double picScale = pictureQueryRequest.getPicScale();
        String picFormat = pictureQueryRequest.getPicFormat();
        String searchText = pictureQueryRequest.getSearchText();
        Long userId = pictureQueryRequest.getUserId();
        String sortField = pictureQueryRequest.getSortField();
        String sortOrder = pictureQueryRequest.getSortOrder();
        Integer reviewStatus = pictureQueryRequest.getReviewStatus();
        Long spaceId = pictureQueryRequest.getSpaceId();
        boolean nullSpaceId = pictureQueryRequest.isNullSpaceId();
        Date startEditTime = pictureQueryRequest.getStartEditTime();
        Date endEditTime = pictureQueryRequest.getEndEditTime();

        if (StrUtil.isNotBlank(searchText)) {
            pictureQueryWrapper.and(pictureQueryWrapper1 ->
                    pictureQueryWrapper1.like("name", searchText)
                            .or()
                            .like("introduction", searchText));
        }

        pictureQueryWrapper.eq(ObjUtil.isNotEmpty(id), "id", id);
        pictureQueryWrapper.eq(ObjUtil.isNotEmpty(userId), "userId", userId);
        pictureQueryWrapper.like(ObjUtil.isNotEmpty(name), "name", name);
        pictureQueryWrapper.like(ObjUtil.isNotEmpty(introduction), "introduction", introduction);
        pictureQueryWrapper.like(ObjUtil.isNotEmpty(picFormat), "picFormat", picFormat);
        pictureQueryWrapper.eq(StrUtil.isNotBlank(category), "category", category);
        pictureQueryWrapper.eq(ObjUtil.isNotEmpty(picWidth), "picWidth", picWidth);
        pictureQueryWrapper.eq(ObjUtil.isNotEmpty(picHeight), "picHeight", picHeight);
        pictureQueryWrapper.eq(ObjUtil.isNotEmpty(picSize), "picSize", picSize);
        pictureQueryWrapper.eq(ObjUtil.isNotEmpty(picScale), "picScale", picScale);
        pictureQueryWrapper.eq(ObjUtil.isNotEmpty(reviewStatus), "reviewStatus", reviewStatus);
        pictureQueryWrapper.eq(ObjUtil.isNotEmpty(spaceId), "spaceId", spaceId);
        pictureQueryWrapper.isNull(nullSpaceId, "spaceId");
        pictureQueryWrapper.lt(ObjUtil.isNotEmpty(endEditTime), "editTime", endEditTime);
        pictureQueryWrapper.gt(ObjUtil.isNotEmpty(startEditTime), "editTime", startEditTime);

        if (CollUtil.isNotEmpty(tags)) {
            for (String tag : tags) {
                pictureQueryWrapper.like("tags", "\"" + tag + "\"");
            }
        }
        pictureQueryWrapper.orderBy(StrUtil.isNotBlank(sortField), sortOrder.equals("ascend"), sortField);

        return pictureQueryWrapper;
    }

    /**
     * 普通用户获取脱敏后的图片分页数据
     *
     * @param pictureQueryRequest
     * @return
     */
    @Override
    public Page<PictureVO> getPicPageVO(PictureQueryRequest pictureQueryRequest) {
        Page<Picture> picturePage = page(
                new Page<>(
                        pictureQueryRequest.getCurrent(),
                        pictureQueryRequest.getPageSize()),
                composePicQueryWrapper(pictureQueryRequest));

        //进行脱敏处理
        return castPicPageToPicPageVO(picturePage);
    }

    /**
     * 将Picture对象脱敏
     *
     * @param pic
     * @return
     */
    @Override
    public PictureVO castPicToPicVO(Picture pic) {
        PictureVO pictureVO = PictureVO.objToVo(pic);
        //设置用户
        if (ObjUtil.isNotEmpty(pic.getUserId())) {
            pictureVO.setUser(userService.castUserToUserVo(userService.getById(pic.getUserId())));
        }
        return pictureVO;
    }

    @Override
    public void fillCheckParams(Picture pic, User user, boolean isUpdate) {
        String userRole = user.getUserRole();
        if (userRole.equals(UserConstant.ADMIN_ROLE)) {
            pic.setReviewStatus(PictureReviewStatusEnum.PASS.getValue());
            pic.setReviewMessage("管理员上传/修改自动审批通过");
        } else {
            pic.setReviewStatus(PictureReviewStatusEnum.REVIEWING.getValue());
        }
        if (isUpdate) {
            pic.setReviewMessage(null);
        }
        pic.setReviewerId(user.getId());
        pic.setReviewTime(new Date());
    }


    @Override
    public Boolean adminApprovePicture(PictureReviewRequest pictureReviewRequest, HttpServletRequest httpServletRequest) {
        Integer reviewStatus = pictureReviewRequest.getReviewStatus();
        //校验前端传递的审批状态
        PictureReviewStatusEnum enumByValue = PictureReviewStatusEnum.getEnumByValue(reviewStatus);
        ThrowUtils.throwIf(ObjUtil.isEmpty(enumByValue), ErrorCode.PARAMS_ERROR);
        Picture picture = new Picture();
        BeanUtils.copyProperties(pictureReviewRequest, picture);
        picture.setReviewerId(userService.getLoginUser(httpServletRequest).getId());
        return updateById(picture);
    }

    /**
     * 管理员批量抓取图片
     * todo 优化点：图片抓取记录表，记录某个关键词 抓取了多少张图片和批次
     *
     * @param pictureUploadByBatchRequest
     * @param httpServletRequest
     * @return
     */
    @Override
    public Integer adminFetchPicture(PictureUploadByBatchRequest pictureUploadByBatchRequest, HttpServletRequest httpServletRequest) {
        String searchText = pictureUploadByBatchRequest.getSearchText();
        Integer count = pictureUploadByBatchRequest.getCount();
        Integer batch = pictureUploadByBatchRequest.getBatch();

//        ThrowUtils.throwIf(count > 30, ErrorCode.OPERATION_ERROR, "批量获取图片，不能超过30张");
//        ThrowUtils.throwIf(batch > 6, ErrorCode.OPERATION_ERROR, "批量获取图片，批次不能超过6批");
        User loginUser = userService.getLoginUser(httpServletRequest);

        int totalCount = 0;
        for (Integer i = 0; i < batch; i++) {
            //首先查询该关键字有无搜索记录
            PictureFetchRecord pictureFetchRecord= pictureFetchRecordService.lambdaQuery().eq(PictureFetchRecord::getKeyWord, searchText).one();
            // 要抓取的地址
            //假设count 是5
            String fetchUrl = String.format("https://cn.bing.com/images/async?q=%s&mmasync=1&first=%s", searchText,
                    ObjUtil.isEmpty(pictureFetchRecord) ? 1 : pictureFetchRecord.getCurrentOffset() + count);
            //解析document
            Document document;
            try {
                document = Jsoup.connect(fetchUrl).get();
            } catch (IOException e) {
                log.error("获取页面失败", e);
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "获取页面失败");
            }
            Element div = document.getElementsByClass("dgControl").first();
            if (ObjUtil.isNull(div)) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "获取元素失败");
            }
            Elements imgElementList = div.select("img.mimg");
            int uploadCount = 0;
            for (Element imgElement : imgElementList) {
                String fileUrl = imgElement.attr("src");
                if (StrUtil.isBlank(fileUrl)) {
                    log.info("当前链接为空，已跳过: {}", fileUrl);
                    continue;
                }
                // 处理图片上传地址，防止出现转义问题
                int questionMarkIndex = fileUrl.indexOf("?");
                if (questionMarkIndex > -1) {
                    fileUrl = fileUrl.substring(0, questionMarkIndex);
                }
                // 上传图片
                PictureUploadRequest pictureUploadRequest = new PictureUploadRequest();
                try {
                    pictureUploadRequest.setPicName(searchText + "(" + System.currentTimeMillis() + ")");

                    PictureVO pictureVO = this.uploadPicture(fileUrl, pictureUploadRequest, loginUser);
                    log.info("图片上传成功, id = {}", pictureVO.getId());
                    uploadCount++;
                    totalCount++;
                } catch (Exception e) {
                    log.error("图片上传失败", e);
                    continue;
                }
                if (uploadCount >= count) {
                    break;
                }
            }
            if (ObjUtil.isEmpty(pictureFetchRecord)){
                PictureFetchRecord record = new PictureFetchRecord();
                record.setKeyWord(searchText);
                record.setUserId(loginUser.getId());
                record.setCurrentOffset(1);
                pictureFetchRecordService.save(record);
            }else {
                pictureFetchRecord.setCurrentOffset(pictureFetchRecord.getCurrentOffset() + count);
                pictureFetchRecordService.updateById(pictureFetchRecord);
            }
        }

        return totalCount;
    }

    /**
     * 删除云端图片
     *
     * @param pic
     */
    @Override
    public void deletePic(Picture pic) {
        String url = pic.getUrl();
        //判断图片是否被多个用户所引用，应对秒传场景
        Long count = lambdaQuery().eq(Picture::getUrl, url).count();
        if (count > 1) {
            return;
        }
        //清理原图
        cosManager.delObject(url);
        //清理webp图片
        String thumbnailUrl = pic.getThumbnailUrl();
        if (StrUtil.isNotBlank(thumbnailUrl)) {
            cosManager.delObject(thumbnailUrl);
        }
    }

    @Override
    public void vaildPictureAuth(Picture picture, HttpServletRequest httpServletRequest) {
        //分为两种情况，有空间ID和没有空间ID，如果没有空间ID，就是删除公共图库
        Long userId = picture.getUserId();
        User loginUser = userService.getLoginUser(httpServletRequest);
        //权限校验 公共图库
        if (picture.getSpaceId() == null) {
            ThrowUtils.throwIf(!loginUser.getUserRole().equals(UserConstant.ADMIN_ROLE) && !Objects.equals(loginUser.getId(), userId),
                    ErrorCode.NO_AUTH_ERROR, "无权操作查看！");
        } else {
            ThrowUtils.throwIf(!Objects.equals(loginUser.getId(), userId),
                    ErrorCode.NO_AUTH_ERROR, "无权操作查看！");
        }
    }

    /**
     * 删除图片
     *
     * @param deleteRequest
     * @param httpServletRequest
     * @return
     */
    @Override
    public Boolean deletePicById(DeleteRequest deleteRequest, HttpServletRequest httpServletRequest) {
        //校验要删除的图片是否存在
        Long id = deleteRequest.getId();
        Picture pic = getById(id);
        ThrowUtils.throwIf(ObjUtil.isEmpty(pic), ErrorCode.OPERATION_ERROR, "该图片不存在！");
        //私有图库，只有用户自身可以操作，公共图库，管理员和用户自身都可以操作
//        vaildPictureAuth(pic, httpServletRequest);

        transactionTemplate.execute(status -> {
            //删除本地图片
            ThrowUtils.throwIf(!removeById(id), ErrorCode.OPERATION_ERROR, "图片删除失败！");
            Long spaceId = pic.getSpaceId();
            if (spaceId != null)
            //释放额度
            {

                ThrowUtils.throwIf(!spaceService.lambdaUpdate().eq(Space::getId, spaceId)
                        .setSql("totalSize = totalSize - " + pic.getPicSize())
                        .setSql("totalCount = totalCount - 1")
                        .update(), ErrorCode.OPERATION_ERROR, "释放额度失败！");
            }
            //删除云端图片
            deletePic(pic);
            return null;
        });
        return true;
    }

    /**
     * 根据颜色搜图
     *
     * @param searchPictureByColorRequest 图片空间 图片颜色值
     * @param loginUser                   用户登录信息
     * @return
     */
    @Override
    public List<PictureVO> searchPicByColor(SearchPictureByColorRequest searchPictureByColorRequest, User loginUser) {
        String picColor = searchPictureByColorRequest.getPicColor();
        Long spaceId = searchPictureByColorRequest.getSpaceId();
        //校验图片空间是否是属于当前用户的
        Space space = spaceService.getById(spaceId);
        ThrowUtils.throwIf(ObjUtil.isEmpty(space), ErrorCode.OPERATION_ERROR, "未查询到空间！");
        ThrowUtils.throwIf(!space.getUserId().equals(loginUser.getId()), ErrorCode.OPERATION_ERROR, "只能在自己的空间中进行搜索！");
        //获取空间下的所有颜色不为空的图片
        List<Picture> pictures = lambdaQuery().eq(Picture::getSpaceId, spaceId).isNotNull(Picture::getPicColor).list();
        if (CollUtil.isEmpty(pictures)) {
            return Collections.emptyList();
        }
        //将目标颜色转换为color对象
        Color targetColor = Color.decode(picColor);
        //进行相似度比较
        return pictures.stream().sorted(Comparator.comparingDouble(picture -> {
            Color color = Color.decode(picture.getPicColor());
            return -ColorSimilarUtils.calculateSimilarity(targetColor, color);
        })).limit(12).map(PictureVO::objToVo).collect(Collectors.toList());
    }

    /**
     * 用户批量编辑图片信息
     *
     * @param pictureEditByBatchRequest
     * @param httpServletRequest
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchUserUpdatePic(PictureEditByBatchRequest pictureEditByBatchRequest, HttpServletRequest httpServletRequest) {
        //获取参数
        List<Long> pictureIdList = pictureEditByBatchRequest.getPictureIdList();
        Long spaceId = pictureEditByBatchRequest.getSpaceId();
        String category = pictureEditByBatchRequest.getCategory();
        List<String> tags = pictureEditByBatchRequest.getTags();
        String nameRule = pictureEditByBatchRequest.getNameRule();
        User loginUser = userService.getLoginUser(httpServletRequest);
        Space space = spaceService.getById(spaceId);
        //参数校验
        ThrowUtils.throwIf(CollUtil.isEmpty(pictureIdList), ErrorCode.PARAMS_ERROR, "图片Id为空");
        ThrowUtils.throwIf(ObjUtil.isEmpty(loginUser), ErrorCode.NO_AUTH_ERROR, "无权操作");
        ThrowUtils.throwIf(ObjUtil.isEmpty(space), ErrorCode.OPERATION_ERROR, "空间不存在");
        ThrowUtils.throwIf(!loginUser.getId().equals(space.getUserId()), ErrorCode.OPERATION_ERROR, "只能编辑自己空间的图片信息");
        //根据pictureId查询出原有的图片列表信息
        List<Picture> pictures = lambdaQuery().select(Picture::getId, Picture::getSpaceId)
                .eq(Picture::getSpaceId, spaceId)
                .in(Picture::getId, pictureIdList)
                .list();
        long count = 1;
        //进行更新参数填充
        for (Picture picture : pictures) {
            if (StrUtil.isNotBlank(category)) {
                picture.setCategory(category);
            }
            if (CollUtil.isNotEmpty(tags)) {
                picture.setTags(JSONUtil.toJsonStr(tags));
            }
            if (StrUtil.isNotBlank(nameRule)) {
                try {
                    picture.setName(nameRule.replace("{序号}", String.valueOf(count++)));
                } catch (Exception e) {
                    log.error("名称解析错误：", e);
                    throw new BusinessException(ErrorCode.OPERATION_ERROR, "名称解析错误");
                }
            }
        }
        //更新
        return updateBatchById(pictures);
    }

    /**
     * 创建AI处理图片任务
     *
     * @param request
     * @param httpServletRequest
     * @return
     */
    @Override
    public CreateOutPaintingTaskResponse createPicHandletask(CreatePictureOutPaintingTaskRequest request, HttpServletRequest httpServletRequest) {
        //参数校验
        Picture picture = getById(request.getPictureId());
        ThrowUtils.throwIf(ObjUtil.isEmpty(picture), ErrorCode.OPERATION_ERROR, "未查询到图片！");
//        vaildPictureAuth(picture, httpServletRequest);


        CreateOutPaintingTaskRequest.Parameters parameters = request.getParameters();

        CreateOutPaintingTaskRequest createPictureOutPaintingTaskRequest = new CreateOutPaintingTaskRequest();
        createPictureOutPaintingTaskRequest.setParameters(parameters);
        CreateOutPaintingTaskRequest.Input input = new CreateOutPaintingTaskRequest.Input();
        input.setImageUrl(picture.getUrl());
        createPictureOutPaintingTaskRequest.setInput(input);
        return aliyunAIService.createTaskHttpPost(createPictureOutPaintingTaskRequest);
    }

    /**
     * 查询AI处理图片任务结果
     * @param taskId
     * @return
     */
    @Override
    public GetOutPaintingTaskResponse queryPicHandletask(String taskId) {
        return aliyunAIService.createQueryTaskResHttpGet(taskId);
    }


    /**
     * 用户查询图片脱敏，特殊处理PictureVO中的User
     *
     * @param picturePage
     * @return
     */
    private Page<PictureVO> castPicPageToPicPageVO(Page<Picture> picturePage) {
        Page<PictureVO> pictureVOPage = new Page<>(picturePage.getCurrent(), picturePage.getSize(), picturePage.getTotal());
        List<Picture> pictures = picturePage.getRecords();
        if (CollUtil.isEmpty(pictures)) {
            return pictureVOPage.setRecords(null);
        }
        //利用PictureVO的objToVo方法，将pictures转化为pictureVOS
        List<PictureVO> pictureVOS = pictures.stream().map(PictureVO::objToVo).collect(Collectors.toList());

        //获取pictures中的所有userId并且去重
        Set<Long> userIds = pictures.stream().map(Picture::getUserId).collect(Collectors.toSet());
        //批量查询用户表
        List<User> users = userService.listByIds(userIds);


        //users 的list转map key是用户id，value是对应的用户
        Map<Long, User> userMap = users.stream()
                .collect(Collectors.toMap(
                        User::getId,
                        Function.identity(),
                        (existingValue, newValue) -> newValue  // 第三个参数：重复键时的合并规则
                ));

        //填充user,处理tags
        for (PictureVO pictureVO : pictureVOS) {
            Long userId = pictureVO.getUserId();
            User user = null;
            if (userMap.containsKey(userId)) {
                user = userMap.get(userId);
            }
            //user对象还需要再次转成userVO
            pictureVO.setUser(userService.castUserToUserVo(user));
        }
        return pictureVOPage.setRecords(pictureVOS);
    }


}





